package com.ruiao.car.utils;


import com.ruiao.car.enums.OsTypeEnums;
import com.ruiao.car.utils.annotation.NoSign;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * 登录拦截器
 *
 * @author Vincent.Pei
 * @date 2019/3/8上午10:34
 * @Description:
 */
@Slf4j
public class LoginInterceptorUtil {


    /**
     * 校验签名
     * @param noSignAnnotation
     * @param request
     * @param headerUtil
     * @param secretKey
     * @return
     * @throws Exception
     */
    public static boolean checkSign(NoSign noSignAnnotation, HttpServletRequest request, HeaderUtil headerUtil, String secretKey) throws Exception{

        /** osType是anonymous、op、server或者加了NoSign不要验签 **/
        String osType = headerUtil.getOsType();
        if (noSignAnnotation != null || OsTypeEnums.anonymous.name().equals(osType)
                || OsTypeEnums.op.name().equals(osType)|| OsTypeEnums.server.name().equals(osType)) {

            return true;
        }

        if( StringUtils.isBlank(secretKey)){
            log.error("no secretKey ...");
            throw new IllegalRequestException("非法操作");
        }

        String httpMethod = request.getMethod();
        /** 格式：api.langfortune.vip/member-futures/coupon/getCouponTab **/
        String requestUrl = request.getRequestURL().substring(request.getRequestURL().indexOf("//") + 2);
        String queryString = request.getQueryString();
        if (StringUtils.isNotBlank(queryString)) {
            requestUrl += "?" + queryString;
        }
        String body = readAsChars(request);
        String toSign = String.format("body=%s&method=%s&nonce=%s&path=%s&ts=%s", body, httpMethod,
                headerUtil.getNonce(), requestUrl, headerUtil.getTs());
        String mySign = sign(secretKey, toSign);
        log.debug("toSign {},secretKey {},appSign {}", toSign, mySign, headerUtil.getSignature());

        if (!mySign.equals(headerUtil.getSignature())) {
            log.error(" sign incorrect ...");
            throw new IllegalRequestException("非法操作");
        }
        return true;
    }



    public static String sign(String accessSecret, String stringToSign) throws Exception {
        javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
        mac.init(new javax.crypto.spec.SecretKeySpec(accessSecret.getBytes("UTF-8"), "HmacSHA1"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        return new sun.misc.BASE64Encoder().encode(signData);
    }

    public static String readAsChars(HttpServletRequest request) throws Exception{
        //文件流不解析body,base64太长不解析
        if (request.getRequestURL() != null && request.getRequestURL().indexOf("base64") != -1 ||
                request.getContentType() != null && request.getContentType().indexOf("multipart/form-data") != -1) {
            return "";
        }
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder("");
        try {
            br = request.getReader();
            String str;
            while ((str = br.readLine()) != null) {
                sb.append(str);
            }
            br.close();
        } catch (NullPointerException e) {
            log.info("readAsChars NullPointerException ignore ");
        } catch (Exception e) {
            log.error("readAsChars error : ", e);
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    log.error("readAsChars close error :", e);
                }
            }
        }
        return sb.toString();
    }



}